﻿using OpenCvSharp;
using OpenGL;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.Drawing;
using System.Linq;

namespace DirectXTest.Src
{
    public class OpenGLTestCurverForm : GameWindow
    {
        public OpenGLTestCurverForm()
            : base(400, 400, OpenTK.Graphics.GraphicsMode.Default, "123", GameWindowFlags.Default, DisplayDevice.Default)
        {
        }

        //List<Vector3> CPoints = new List<Vector3>();
        float[][][] CPoints = new float[3][][];

        private int CurrentTexture;
        public Mat CurrentMat { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.AutoNormal);
            GL.Enable(EnableCap.Normalize);
            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
            GL.GenTextures(1, out CurrentTexture);
            GL.BindTexture(TextureTarget.Texture2D, CurrentTexture);
            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            VideoCapture videoCapture = new VideoCapture("D:\\迅雷下载\\mov_bbb.mp4");
            CurrentMat = new Mat();
            videoCapture.Read(CurrentMat);
            videoCapture.Dispose();

            for (int i = 0; i < CPoints.Length; i++)
            {
                CPoints[i] = new float[3][];
            }
            CPoints[0][0] = new float[3] { -0.5f, 0.5f, 0 };
            CPoints[0][1] = new float[3] { 0, 0.5f, 0 };
            CPoints[0][2] = new float[3] { 0.5f, 0.5f, 0 };

            CPoints[1][0] = new float[3] { -0.5f, 0, 0 };
            CPoints[1][1] = new float[3] { 0, 0, 0 };
            CPoints[1][2] = new float[3] { 0.5f, 0, 0 };

            CPoints[2][0] = new float[3] { -0.5f, -0.5f, 0 };
            CPoints[2][1] = new float[3] { 0, -0.5f, 0 };
            CPoints[2][2] = new float[3] { 0.5f, -0.5f, 0 };


            /*         CPoints.Add(new Vector3(-0.5f, 0.5f, 0));
                     CPoints.Add(new Vector3(0, 0.5f, 0));
                     CPoints.Add(new Vector3(0.5f, 0.5f, 0));
                     CPoints.Add(new Vector3(-0.5f, 0, 0));
                     CPoints.Add(new Vector3(0, 0, 0));
                     CPoints.Add(new Vector3(0.5f, 0, 0));
                     CPoints.Add(new Vector3(-0.5f, -0.5f, 0));
                     CPoints.Add(new Vector3(0, -0.5f, 0));
                     CPoints.Add(new Vector3(0.5f, -0.5f, 0));*/
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            GL.Viewport(ClientRectangle);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            Title = $"(Vsync: {VSync}) FPS: {1f / e.Time:0}";
            base.OnRenderFrame(e);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, CurrentMat.Width, CurrentMat.Height, 0, PixelFormat.Bgr, PixelType.UnsignedByte, CurrentMat.Data);
            /*            GL.Begin(BeginMode.TriangleStrip);
                        for (int i = 0; i < CPoints.Count; i++)
                        {
                            GL.TexCoord2(CPoints[i].X, CPoints[i].Y);
                            GL.Vertex3(CPoints[i]);
                        }
                        GL.End();*/


            object qua = GLU.gluNewQuadric();
            GLU.gluQuadricTexture(ref qua, (byte)GLU.GLU_TRUE);
            GLU.gluQuadricDrawStyle(ref qua, GLU.GLU_FILL);


            GL.Color3(1.0, 1.0, 0);
            float[] sknot = new float[9] { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f };
            IntPtr intPtr = GLU.gluNewNurbsRenderer();
            GLU.gluNurbsProperty(intPtr, GLU.GLU_SAMPLING_TOLERANCE, 5.0f);


            GLU.gluNurbsProperty(intPtr, GLU.GLU_DISPLAY_MODE, GLU.GLU_FILL);
            GLU.gluBeginSurface(intPtr);
            GLU.gluNurbsSurface(intPtr, sknot.Length, sknot, sknot.Length, sknot, 15, 3, CPoints[0][0], 4, 4, (uint)MapTarget.Map2Vertex3);
            GLU.gluEndSurface(intPtr);

            GL.Color3(1.0, 0, 0);
            GL.PointSize(10);
            GL.Begin(BeginMode.Points);
            for (int i = 0; i < CPoints.Length; i++)
            {
                for (int j = 0; j < CPoints.Length; j++)
                {
                    GL.Vertex3(CPoints[i][j][0], CPoints[i][j][1], 0.0f);
                }
            }
            GL.End();
            SwapBuffers();
        }
    }
}